/*
 * GeoVISTA Center (Penn State, Dept. of Geography)
 * Copyright (c), 2003-2011,  Jin Chen and Alan M. MacEachren, GeoVISTA Center, Penn State University
 * Licensed under Simplified BSD License
 *
 *
 * @Original Author: jin Chen
 * @date: Sep 8, 2004$
 * @version: 1.0
 */
package edu.psu.geovista.data.model;

import org.apache.commons.beanutils.BeanUtils;

import javax.swing.table.DefaultTableModel;
import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.Vector;

public class BasicMetadataModel extends DefaultTableModel implements MetadataModel {//DefaultTableModel
     protected int IdColumn=0;// the index of the column, an element of which serve the id of a row



    /**
     * Deal with data (Object[]) generated by CSVMetaFileReader. The data is of this format:
     * - object[0]: column names
     * - object[n] the nth column
     * @param raw
     */
    public void feedCVSMetaData(Object[] raw){
          //this.clone();

        Object[] colNames = (Object[]) raw[0];
        for (int i=0;i<colNames.length ;i++){
            Object colName = colNames[i];
            Object[] colValue=(Object[]) raw[i+1];
            this.addColumn(colName,colValue);
        }
        //this.setColumnIdentifiers(colNames);
    }
    /**************************************************
     *                sort
     ***************************************************/
    public void sort(String colname) {
        int colIndex = this.getColumnIndexByNameIgnoreCase(colname);
        if(colIndex>=0)
        sort(colIndex);


    }

    public  void sort(int colIndex) {
        VectorComparator vcmp=new VectorComparator(colIndex);
        Collections.sort(this.dataVector,vcmp);
    }

    /**************************************************
     *        get data
     ***************************************************/
     public Object[] getColumnAsArray(int index){
        if(index<0){
           new IllegalArgumentException(this.getClass().getName() +" is passed a negative data");
        }
        Object[] value=new Object[this.dataVector.size()];
        Enumeration e = dataVector.elements();
        int i=0;
        while (e.hasMoreElements()) {
            Vector row = (Vector) e.nextElement();
            value[i++]  = row.get(index);
          }
        return value;
    }
    public Object[] getColumn(String colname){
        int index = this.getColumnIndexByName(colname);
        if(index>=0){
        return this.getColumnAsArray(index);
        }
        else{
            return new Object[0];
        }

    }
     public Object getRowId(int row){
         return this.getValueAt(row,IdColumn) ;
     }

    /**
     *
     * @param colName
     * @return    -1 if can't find the name
     */
    public int getColumnIndexByName(String colName){
        Enumeration e=this.columnIdentifiers.elements() ;
        int index=0;
        while(e.hasMoreElements() ){

            Object o = e.nextElement();
            String id=null;
            if(o instanceof Column){
            id=((Column)o).getId() ;
            }
            else if(o instanceof String ){
                id=(String) o;
            }
            //String id=(String)e.nextElement() ;
            if(id.equals(colName) )
                return index;
            index++;
        }
        return -1;
    }

    /**
         *
         * @param colName
         * @return    -1 if can't find the name
         */
        public int getColumnIndexByNameIgnoreCase(String colName){
            Enumeration e=this.columnIdentifiers.elements() ;
            int index=0;
            while(e.hasMoreElements() ){

                Object o = e.nextElement();
                String id=null;
                if(o instanceof Column){
                id=((edu.psu.geovista.data.model.Column)o).getId() ;
                }
                else if(o instanceof String ){
                    id=(String) o;
                }
                //String id=(String)e.nextElement() ;
                if(id!=null&&id.equalsIgnoreCase(colName) )
                    return index;

                index++;
            }
            return -1;
        }


    public int getIdColumn() {
        return IdColumn;
    }

    public void setIdColumn(int idColumn) {
        IdColumn = idColumn;
    }


    class SortElement implements Comparable{
        Comparable target;
        int index;

        public int compareTo(Object o) {
            SortElement another=(SortElement) o;
            return this.target.compareTo(another.target );
            //return 0;  //To change body of implemented methods use File | Settings | File Templates.
        }
    }

    public Object clone() {
        //Hashtable columnDespt=(Hashtable) this.getColumndescription().clone();
        BasicMetadataModel model=new BasicMetadataModel();

        try {
            // 
            // 
            BeanUtils.copyProperties(model,this);

        } catch (IllegalAccessException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (InvocationTargetException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
        return model;
    }
    class VectorComparator implements Comparator{
        int index; // the index of the element which is used for comparision

        public VectorComparator(int index) {
            this.index = index;
        }

        public int compare(Object o1, Object o2) {
            Vector v1=(Vector) o1;
            Vector v2=(Vector) o2;
            Comparable e1=(Comparable) v1.get(getIndex());
            Comparable e2=(Comparable) v2.get(getIndex());
            return e1.compareTo(e2);
            //return ;
        }

        public int getIndex() {
            return index;
        }

        public void setIndex(int index) {
            this.index = index;
        }

    }

  /*  public void add(BasicMetatdataModel model){
        Vector datav = model.getDataVector();
        Vector columnIds = model.getColumnIdentifiers();
        this.dataVector.addAll(datav);
        this.columnIdentifiers.add(columnIds);
    }
    public Vector getColumnIdentifiers(){
        return this.columnIdentifiers ;
    }*/

}
